#include "pch.h"
#include "geVector3d.h"

glm::dvec3 toPt3d(const jm::gePoint3d& pt)
{
    return glm::dvec3(pt.x, pt.y, pt.z);
}

glm::dvec3 toPt3d(const jm::geVector3d& pt)
{
    return glm::dvec3(pt.x, pt.y, pt.z);
}

namespace jm
{

geVector3d geVector3d::kX{ 1.0, 0.0, 0.0 };
geVector3d geVector3d::kY{ 0.0, 1.0, 0.0 };
geVector3d geVector3d::kZ{ 0.0, 0.0, 1.0 };

void geVector3d::set(double _x, double _y, double _z)
{
    x = _x;
    y = _y;
    z = _z;
}

geVector3d geVector3d::crossProduct(const geVector3d& vec) const
{
    glm::dvec3 tmp = glm::cross(toPt3d(*this), toPt3d(vec));
    return geVector3d(tmp.x, tmp.y, tmp.z);
}

double geVector3d::dotProduct(const geVector3d& vec) const
{
    return glm::dot(toPt3d(*this), toPt3d(vec));
}

geVector3d geVector3d::normal() const
{
    glm::dvec3 tmp = glm::normalize(toPt3d(*this));
    return geVector3d(tmp.x, tmp.y, tmp.z);
}

geVector3d& geVector3d::normalize()
{
    glm::dvec3 tmp = glm::normalize(toPt3d(*this));
    x = tmp.x;
    y = tmp.y;
    z = tmp.z;
    return *this;
}

geVector3d& geVector3d::operator*(double s)
{
    x *= s;
    y *= s;
    z *= s;
    return *this;
}

double geVector3d::length() const
{
    return glm::length(toPt3d(*this));
}

bool geVector3d::isOrthogonal(const geVector3d& pt, double prec/* = jm::precision*/) const
{
    return jm::equal(pt.dotProduct(*this), 0.0, prec);
}

bool geVector3d::isParallel(const geVector3d& pt, double prec) const
{
    double v = pt.dotProduct(*this);
    return jm::equal(v, 1.0, prec) || jm::equal(v, -1.0, prec);
}

bool geVector3d::isCodirectional(const geVector3d& pt, double prec) const
{
    return jm::equal(pt.dotProduct(*this), 1.0, prec);
}

geVector3d& geVector3d::transformBy(const geMatrix3d& xform)
{
    *this = geMatrix3d::preMult(xform, *this);
    return *this;
}

}



